#include "bayes_loop.h"

#include <vector>
#include <cstdlib>
#include <iostream>
#include <ctime>

int main()
{
    // 这是一个 二元假设-二元观察 的例子
    // 我们基于 rand() 函数进行蒙特卡罗测试
    std::srand(std::time(NULL));

    // 这是一个利用贝叶斯方法和贝叶斯循环预测的一个简单例子
    // 本例子中，我们假设我们有两个硬币，其中一个硬币称为硬币F，有 50% 的概率得到正面，有 50% 的概率得到反面
    // 另外一个硬币称为硬币R，有 x% 的概率得到正面，有 (100 - x)% 的概率得到反面
    // 然后我们随机选择其中一个硬币，反复抛出硬币，观察结果，确定我们选择的是哪一个硬币

    // 两种假设的概率
    // 假设 0：我们最开始选的是硬币 F
    // 假设 1：我们最开始选的是硬币 R
    // 最开始我们猜测两种假设的发生概率各是0.5
    // 尝试修改他们，观察假设概率的初始值和迭代次数之间的关系
    std::vector<double> hyp{0.5, 0.5};

    // 上述的 x
    double x = 0.4977777;
    // 我们最开始选择的硬币，0 代表 F，1 代表 R
    int chs = 0;
    // 迭代次数
    int cnt = 100000;

    // 条件概率，在假设 j 发生的情况下，观察 i 发生的概率 obs[i][j] 这是已知的
    // 观察 0：我们得到是正面
    // 观察 1：我们得到是反面
    std::vector<std::vector<double>> obs{{0.5, x}, {0.5, 1 - x}};

    BayesLoop bl(hyp, obs);

    for (int i = 0; i < cnt; i++)
    {
        double th = chs == 0 ? 0.5 : x;
        double rd = (double)std::rand() / RAND_MAX;
        rd < th ? bl.do_loop(0) : bl.do_loop(1);
    }

    // 输出概率

    std::cout << "F:" << bl.get_hyp()[0] << " R:" << bl.get_hyp()[1] << std::endl;

    // 我们发现，即使是 x 多么接近于 0.5 或者初始 hyp 多么离谱，只要迭代次数足够多，其正态分布的均值也会向正确的方向靠拢
    return 0;
}